﻿#include "TableChatWindow.h"
#include "TableDisplayWindow.h"
#include "TableSettings.h"
#include <QSplitter>
#include <QPushButton>
#include <QHBoxLayout>
#include <QDateTime>
#include <QDebug>
#include "BaseWidget/IWidgetSignal.h"
#include "DataManager/WindowTotalData.h"
#include "BaseWidget/IdaDialogMsg.h"
#include "PstSplitter.h"
#include "MainWindowSignalHandler.h"
#include "TableChartWindowSidebarData.h"

namespace pst
{

    TableChatWindow::TableChatWindow(QWidget* parent)
        : Graph3DWindowBase(parent)
        , m_info(nullptr)
    {

        QHBoxLayout* layout = new QHBoxLayout;
        m_tableWidget = new TableDisplayWindow(this);
        m_tableSettings = new TableSettings(this);
        QHeaderView* header = m_tableWidget->horizontalHeader();
        PstSplitter* splitter = new PstSplitter(Qt::Horizontal, this);
        splitter->setStyleSheet("QSplitter::handle { width: 0px; height: 0px; }");
        splitter->setHandleWidth(0);             // 隐藏分割条
        splitter->setChildrenCollapsible(false); // 禁止子部件折叠
        splitter->addWidget(m_tableWidget);
        splitter->addWidget(m_tableSettings);
        m_tableSettings->setFixedWidth(260);
        splitter->setStretchFactor(0, 1);
        splitter->widget(1)->setFixedWidth(260);
        splitter->widget(0)->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
        layout->addWidget(splitter);
        this->setLayout(layout);
        connect(m_tableSettings, &pst::TableSettings::signal_showOrHideColumn, this, &pst::TableChatWindow::hideOrShowTableColumn);
        connect(m_tableSettings, &pst::TableSettings::signal_highlightSelectedTableColumns, this, &pst::TableChatWindow::highlightSelectedTableColumns);
        connect(m_tableSettings, &pst::TableSettings::signal_changeColumnName, this, &pst::TableChatWindow::changeColumnName);
        connect(m_tableSettings, &pst::TableSettings::signal_flushTableBySelectedRow, this, &pst::TableChatWindow::slot_flushTableBySelectedRow);
        connect(m_tableSettings, &pst::TableSettings::signal_importShowOrHideColumn, this, &pst::TableChatWindow::hideOrShowTableColumn);
        connect(m_tableSettings, &pst::TableSettings::signal_importChangeColumnName, this, &pst::TableChatWindow::tableColRename);
        connect(IWidgetSignalInstance, &BaseWidget::IWidgetSignal::signal_closeTree, this, &TableChatWindow::slot_closeTree);

    }

    TableChatWindow::~TableChatWindow()
    {
    }

    void TableChatWindow::addDataToWindow(InfomationGraph3DBasical* info)
    {
        m_tableWidget->addDataToWindow(info);
        m_info = info;
        auto TableChartWindowSidebarData = new pst::TableChartWindowSidebarData(this);
        m_info->m_TableChartWindowSidebarData = TableChartWindowSidebarData;
        m_tableSettings->setTableChartDataInfo(info);
        if (!GlobalHelperInstance->getIsOpenProject())
            info->m_informationID = WindowTotalDataInstance->getGraph3DInformationMaxID();
        WindowTotalDataInstance->appendInfomationGraph3DBasical(info);
    }

    void TableChatWindow::setWindowID(int windowID)
    {
        m_tableChatWindowID = windowID;
    }
    int TableChatWindow::getWindowID() const
    {
        return m_tableChatWindowID;
    }

    void TableChatWindow::setWindowUniversalID(int windowUniversalID)
    {
        m_windowUniversalID = windowUniversalID;
    }
    int TableChatWindow::getWindowUniversalID() const
    {
        return m_windowUniversalID;
    }

    QDomElement& TableChatWindow::writeToProjectFile(QDomDocument* doc, QDomElement* element, bool isdiso)
    {
        QDomElement _TableChatWindowDataRoot = doc->createElement("GraphWindow");
        QDomAttr _WindowUniversalIDattr = doc->createAttribute("WindowUniversalID");
        _WindowUniversalIDattr.setValue(QString::number(m_windowUniversalID));
        _TableChatWindowDataRoot.setAttributeNode(_WindowUniversalIDattr);
        QDomAttr _idattr = doc->createAttribute("WindowID");
        _idattr.setValue(QString::number(m_tableChatWindowID));
        _TableChatWindowDataRoot.setAttributeNode(_idattr);
        QDomAttr typeattr = doc->createAttribute("WindowType");
        typeattr.setValue("TableChatWindow");
        _TableChatWindowDataRoot.setAttributeNode(typeattr);

        element->appendChild(_TableChatWindowDataRoot);
        if (m_info != nullptr)
            m_info->writeToProjectFile(doc, &_TableChatWindowDataRoot, GraphType::TableChart, isdiso);

        return _TableChatWindowDataRoot;
    }

    void TableChatWindow::readFromProjectFile(QDomElement* element, bool isdiso)
    {
        m_windowUniversalID = element->attribute("WindowUniversalID").toInt();
        int id = element->attribute("WindowID").toInt();
        m_tableChatWindowID = id;

        auto _infosNodeList = element->elementsByTagName("InfomationGraph3DBasical");
        auto _infosCount = _infosNodeList.count();
        if (_infosCount != 1)
            return;

        QDomElement elemModel = _infosNodeList.at(0).toElement();
        auto _ProjectTreeSourceItemID = elemModel.attribute("ProjectTreeSourceItemID").toInt();
        if (_ProjectTreeSourceItemID != -1)
        {
            auto info = MainWindowSignalHandlerInstance->BuildCompleteGraph3DInfoByProjectTreeItem(_ProjectTreeSourceItemID, GraphType::TableChart);
            this->addDataToWindow(info);
            this->setTableDataInfo();
            this->setTableDataSource(info->m_dataSources);
            this->addDataFilterVarItem();
            info->readFromProjectFile(&elemModel, GraphType::TableChart, isdiso);

            m_tableSettings->updataTableChartDataByOpenProject();    
        }
        
    }

    void TableChatWindow::setTableDataInfo()
    {
        m_tableSettings->addData(m_tableWidget);
    }

    void TableChatWindow::setTableDataSource(QString dataSource) 
    {
        m_tableSettings->setDataSource(dataSource);
    }

    void TableChatWindow::pyHideOrShowTableColumn(QSet<int>& selectedIndexs)
    {
        hideOrShowTableColumn(selectedIndexs, false);
        m_tableSettings->pyHideOrShowTableColumn(selectedIndexs);

    }

    void TableChatWindow::hideOrShowTableColumn(QSet<int>& selectedIndexs, bool savePy) 
    {
        QString indexArgs = "";
        auto _tempDataItemInfo = m_info->m_TableChartWindowSidebarData->getTableDataitemInformationList();
        for (int index : selectedIndexs)
        {
            bool isHidden = m_tableWidget->isColumnHidden(index);
            m_tableWidget->setColumnHidden(index, !isHidden);
            indexArgs += QString::number(index) + "_";
            if (!GlobalHelperInstance->getIsOpenProject())
            {
                TableChartWindowSidebarData::TableDataitemInformation& _tempDataItem = _tempDataItemInfo[index];
                _tempDataItem.m_itemDisplayStatus = isHidden;
                m_info->m_TableChartWindowSidebarData->appendTableDataitemInformation(_tempDataItem);
            }
        }
        if (savePy)
        {
            indexArgs.chop(1);       
            QStringList _pyCodes{};
            indexArgs = "\"" + indexArgs + "\"";
            _pyCodes += QString("tableWidget = PostProcessing.TableWidget()");
            _pyCodes += QString("tableWidget.hideOrShowTableColumn(%1,%2)").arg(m_tableChatWindowID).arg(indexArgs);
            emit IBaseSignalInstance->signal_execPYCode(_pyCodes, true, false);
            
        }
    }

    void TableChatWindow::pyHighlightSelectedTbColumns(QString parms)
    {
        QStringList list = parms.split("_");
        QSet<int> set;
        for (QString s : list)
        {
            set.insert(s.toInt());
        }
        highlightSelectedTbColumns(set, false);
        m_tableSettings->pySetSelectedIndex(set);
    }

    bool TableChatWindow::saveScreenShot(const QString& path)
    {
        // 假设 table 是已填充数据的 QTableWidget*
        QTableWidget* table = m_tableWidget;
        QString suffix = QFileInfo(path).suffix().toUpper();

        QPixmap fullContentPix = table->viewport()->grab();
        QPixmap pixmap(table->size());
        pixmap.fill(Qt::white);  // 可根据需求选背景色
        table->render(&pixmap);

        return pixmap.save(path, suffix.toUtf8().constData());
    }


    void TableChatWindow::highlightSelectedTableColumns(QSet<int>& selectedIndexs)
    {
        highlightSelectedTbColumns(selectedIndexs, true);
    }

    void TableChatWindow::highlightSelectedTbColumns(QSet<int>& selectedIndexs, bool savePy)
    {
        QString parm;
        for (int index : selectedIndexs)
        {
            m_tableWidget->selectColumn(index);
            parm += QString::number(index) + "_";
        }

        if (savePy)
        {
            parm.chop(1);
            QString _parm = "\"" + parm + "\"";
            QStringList _pyCodes{};
            _pyCodes += QString("tableWidget = PostProcessing.TableWidget()");
            _pyCodes += QString("tableWidget.highlightSelectedTbColumns(%1,%2)").arg(m_tableChatWindowID).arg(_parm);
            emit IBaseSignalInstance->signal_execPYCode(_pyCodes, true, false);
        }

    }

    void TableChatWindow::pyRenameColName(int colIndex, QString newName)
    {
        QTableWidgetItem* headerItem = new QTableWidgetItem(newName);
        m_tableWidget->setHorizontalHeaderItem(colIndex, headerItem);
        m_tableSettings->pyChangColName(colIndex, newName);
    }

    bool TableChatWindow::tableColRename(QHash<int, QString>& hash)
    {
        auto it = hash.begin();
        int index = it.key();
        QString newName = it.value();
        if (newName.isEmpty())
        {
            IdaDialogMsg::showDialog(this, QString("命名不能为空，请重新编辑。"), EDialogMsg::Error, tr("重命名错误"));
            return false;
        }

        QHash<int, QString> map;
        for (int colNum = 0; colNum < m_tableWidget->columnCount(); ++colNum)
        {
            QString name = m_tableWidget->horizontalHeaderItem(colNum)->text();
            if (!name.endsWith("key"))
            {
                map.insert(colNum, name);
            }
        }

        if (newName == map.value(index))
        {
            return true;
        }

        if (map.values().contains(newName))
        {
            IdaDialogMsg::showDialog(this, QString("当前名称已存在，请重新编辑。"), EDialogMsg::Error, tr("重命名错误"));
            return false;
        }
        QTableWidgetItem* headerItem = new QTableWidgetItem(newName);
        m_tableWidget->setHorizontalHeaderItem(index, headerItem);

        if (!GlobalHelperInstance->getIsOpenProject())
        {
            auto _tempDataItemInfo = m_info->m_TableChartWindowSidebarData->getTableDataitemInformationList();
            TableChartWindowSidebarData::TableDataitemInformation& _tempDataItem = _tempDataItemInfo[index];
            _tempDataItem.m_itemName = newName;
            _tempDataItem.m_isReNamed = true;
            m_info->m_TableChartWindowSidebarData->appendTableDataitemInformation(_tempDataItem);
        }

        return true;
    }

    void TableChatWindow::changeColumnName(QHash<int, QString>& hash, bool& execRes)
    {
        execRes = tableColRename(hash);
        if (execRes)
        {
            auto it = hash.begin();
            int index = it.key();
            QString newName = "\"" + it.value() + "\"";
            QStringList _pyCodes{};
            _pyCodes += QString("tableWidget = PostProcessing.TableWidget()");
            _pyCodes += QString("tableWidget.changeTbColumnName(%1,%2,%3)").arg(m_tableChatWindowID).arg(index).arg(newName);
            emit IBaseSignalInstance->signal_execPYCode(_pyCodes, true, false);
        }
    }

    void TableChatWindow::addDataFilterVarItem()
    {
        m_tableSettings->addDataFilterVarItem(m_tableWidget);
    }

    void TableChatWindow::pyFlushTableBySelectedRow(QString parms)
    {
        QHash<int, QStringList> map = GlobalHelperInstance->base64ToHash(parms);
        flushTableBySelectedRow(map, false);
        m_tableSettings->pyFlushTableBySelectedRow(map);
    }

    void TableChatWindow::slot_flushTableBySelectedRow(QHash<int, QStringList> map, bool savePy)
    {
        flushTableBySelectedRow(map, savePy);
    }

    void TableChatWindow::flushTableBySelectedRow(QHash<int, QStringList> map, bool savePy)
    {
        IBaseSignalInstance->signal_UpdateStatusBarInformation(QString("表格数据筛选正在进行中..."), true);
        QCoreApplication::processEvents();

        for (int rowNum = 0; rowNum < m_tableWidget->rowCount(); ++rowNum)
        {
            bool isHidden = false;
            for (int colNum = 0; colNum < m_tableWidget->columnCount(); ++colNum)
            {
                QString value = m_tableWidget->item(rowNum, colNum)->text().trimmed();

                if (map.keys().contains(colNum))
                {
                    QStringList selectValues = map[colNum];
                    if (!selectValues.contains(value))
                    {
                        isHidden = true;
                        break;
                    }
                }
            }
            m_tableWidget->setRowHidden(rowNum, isHidden);
        }
        IBaseSignalInstance->signal_UpdateStatusBarInformation(QString("表格数据筛选成功！"), false);

        if (savePy)
        {
            QString args = "\"" + GlobalHelperInstance->hashToBase64(map) + "\"";
            QStringList _pyCodes{};
            _pyCodes += QString("tableWidget = PostProcessing.TableWidget()");
            _pyCodes += QString("tableWidget.flushTbBySelectedRow(%1,%2)").arg(m_tableChatWindowID).arg(args);
            emit IBaseSignalInstance->signal_execPYCode(_pyCodes, true, false);
        }
    }


    void TableChatWindow::slot_closeTree(const QList<QStandardItem*>& items)
    {
        QList<InfomationGraph3DBasical*> itemToDelete;
        for (auto treeItem : items)
        {
            if (m_info == nullptr)
            {
                return;
            }
            if (m_info->m_projectTreeSourceItem == treeItem)
            {
                clearWindow();
                break;
            }
        }
        m_info == nullptr;
    }

    void TableChatWindow::clearWindow()
    {
        m_tableWidget->clear();            // 清空所有单元格内容和头部文字
        m_tableWidget->setRowCount(0);     // 删除所有行
        m_tableWidget->setColumnCount(0);  // 删除所有列

        m_tableSettings->clearData();
        if (m_info != nullptr)
        {
            delete m_info;
            m_info = nullptr;
        }
    }

    bool TableChatWindow::exportTableData(const QString& filePath, const QChar& delimiter, bool onlyVisible, bool savePy )
    {
        QSaveFile file(filePath);
        if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
        {
            return false;
        }
        QTextStream out(&file);
        out.setCodec("UTF-8");

        int totalCols = m_tableWidget->columnCount();
        int totalRows = m_tableWidget->rowCount();

        // 收集需要导出的列索引
        QList<int> cols;
        cols.reserve(totalCols);
        for (int c = 0; c < totalCols; ++c)
        {
            if (!onlyVisible || !m_tableWidget->isColumnHidden(c))
            {
                cols.append(c);
            }
        }

        // 收集需要导出的行索引
        QList<int> rows;
        rows.reserve(totalRows);
        for (int r = 0; r < totalRows; ++r)
        {
            if (!onlyVisible || !m_tableWidget->isRowHidden(r))
            {
                rows.append(r);
            }
        }

        // 写出水平表头
        for (int i = 0; i < cols.size(); ++i)
        {
            int c = cols.at(i);
            QTableWidgetItem* hItem = m_tableWidget->horizontalHeaderItem(c);
            out << (hItem ? hItem->text() : QString());
            if (i < cols.size() - 1)
            {
                out << delimiter;
            }
        }
        out << "\n";

        // 写出每行数据
        for (int rIdx = 0; rIdx < rows.size(); ++rIdx)
        {
            int r = rows.at(rIdx);
            for (int i = 0; i < cols.size(); ++i)
            {
                int c = cols.at(i);
                QTableWidgetItem* item = m_tableWidget->item(r, c);
                out << (item ? item->text() : QString());
                if (i < cols.size() - 1)
                {
                    out << delimiter;
                }
            }
            out << "\n";
        }

        file.commit();

        /*if (savePy)
        {
            QString _filePath = "\"" + filePath + "\"";
            QString _delimiter = "\"" + QString(delimiter) + "\"";
            int _onlyVisible = onlyVisible ? 1 : 0;
            QStringList _pyCodes{};
            _pyCodes += QString("tableWidget = PostProcessing.TableWidget()");
            _pyCodes += QString("tableWidget.exportTbData(%1,%2,%3,%4)").arg(m_tableChatWindowID).arg(_filePath).arg(_delimiter).arg(_onlyVisible);
            emit IBaseSignalInstance->signal_execPYCode(_pyCodes, true, false);
        }*/

        return true;
    }

} // namespace pst
